#include "mod_update_mcu.h"

#include "main.h"
#include "mod_com.h"
#include <fstream>
#include <iostream>
#include <string>    // 对于转换为字符串的操作，需要包含这个头文件
#include <vector>
#include <windows.h>
#include <stddef.h>
#include <stdio.h>

#include <iostream>
#include <fstream>
#include <chrono>
#include <iomanip>
#include <sstream>

using json = nlohmann::json;

#define FC_BOOT_START     0x02    // 开始固件升级，传递包大小以以及总帧数
#define FC_BOOT_FW_BLOCK  0x03    // 固件块烧录
#define FC_BOOT_END       0x04    // 结束固件升级并锁定FLASH（传递总包校验码）
#define FC_REBOOT         0x08    // 板子复位

#define UPDATE_PKGS_SIZE  256    // 一帧数据包大小，每次发送的有效数据必须是这个长度，不足0补齐。
#define FRAME_HEAD_0      0x5A
#define FRAME_HEAD_1      0xA5

#define HEAD_LEN          2                                // 头帧长度
#define CRC_LEN           2                                // CRC校验长度
#define PACK_STRUC_LEN    sizeof(base_msg_max_packet_t)    // 打包结构体长度

#define BTKCP_TYPE_DATA   (0x01)    // 数据帧
#define BTKCP_TYPE_REPLY  (0x02)    // 应答帧
#define BTKCP_TYPE_RESULT (0x03)    // 结果帧
#define BTKCP_TYPE_NOTIFY (0x04)    // 通知帧
#define BTKCP_TYPE_LOCAL  (0x05)    // 本地帧
#define BTKCP_TYPE_MAX    BTKCP_TYPE_LOCAL

#define TIMEOUT_MAX       (3000)    // 超时时间

#pragma pack(push, 1)
typedef struct
{
    uint8_t  magic0;         // 0x5A
    uint8_t  magic1;         // 0xA5
    uint8_t  check_L;        // 校验 低8位
    uint8_t  check_H;        // 校验 高8位
    uint32_t frame_id;       // 帧序号
    uint8_t  type;           // 消息类型
    uint16_t src_module;     // 源模块ID
    uint16_t dst_module;     // 目的模块ID
    uint8_t  fc;             // 功能码
    uint16_t content_len;    // 内容长度
} pack_head_t;

typedef struct __attribute__((packed))
{
    pack_head_t pkg_head;
    uint8_t     content[256];
} base_msg_max_packet_t;

typedef struct __attribute__((packed))
{
    pack_head_t pkg_head;
    int8_t      result;    // 执行结果
    int16_t     index;     // 数据包索引
    int8_t      state;     // 升级状态
} task_ota_fb_t;

#pragma pack(pop)

base_msg_max_packet_t msg_pack_send = {0};
task_ota_fb_t         msg_pack_rece = {0};

base_msg_max_packet_t read_config_json = {0};    // 读取config.json

int curDataIndex = 0;

int     update_file_fd  = -1;
int     update_file_len = 0;
int16_t update_file_idx = 0;    // 当前文件所需传输帧数
FILE   *file            = 0;

// 获取高精度时间戳（毫秒）
long long getHighPrecisionTimeMillis() {
    LARGE_INTEGER frequency, counter;
    QueryPerformanceFrequency(&frequency);
    QueryPerformanceCounter(&counter);
    return (counter.QuadPart * 1000) / frequency.QuadPart;
}

// 获取带毫秒的格式化时间字符串
inline std::string getFormattedTimeWithMillis() {
    auto now        = std::chrono::system_clock::now();
    auto now_time_t = std::chrono::system_clock::to_time_t(now);
    auto now_ms     = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;

    std::stringstream ss;
    ss << std::put_time(std::localtime(&now_time_t), "%Y-%m-%d %H:%M:%S") << '.' << std::setfill('0') << std::setw(3)
       << now_ms.count();
    return ss.str();
}

/**
 * @brief 打包函数
 *
 * @content cmd
 * @content idx
 */
int package_send(int cmd, int idx) {
    uint8_t  com_buf[1024] = "";
    uint32_t pkg_len       = 0;
    uint16_t up_data_len   = 0;

    // 开始固件升级，传递总帧数
    if (cmd == FC_BOOT_START) {
        up_data_len = 2;
        // 固件块烧录
    } else if (cmd == FC_BOOT_FW_BLOCK) {
        up_data_len = UPDATE_PKGS_SIZE;
    } else if (cmd == FC_BOOT_END) {
        // 结束固件升级
        up_data_len = 0;
    }

    memset(&msg_pack_send, 0, sizeof(msg_pack_send));

    memcpy(&msg_pack_send, &read_config_json, sizeof(base_msg_max_packet_t));

    msg_pack_send.pkg_head.magic0     = FRAME_HEAD_0;
    msg_pack_send.pkg_head.magic1     = FRAME_HEAD_1;
    msg_pack_send.pkg_head.frame_id   = idx;                // 帧序号
    msg_pack_send.pkg_head.type       = BTKCP_TYPE_DATA;    // 消息类型
    msg_pack_send.pkg_head.src_module = 0x40;               //
    // msg_pack_send.pkg_head.dst_module  = 0X501;              // 所需升级的传输帧数
    msg_pack_send.pkg_head.fc          = cmd;    // 功能码
    msg_pack_send.pkg_head.content_len = up_data_len;

    // 头帧cpy到数组
    memcpy((char *)com_buf, (char *)&msg_pack_send.pkg_head, sizeof(msg_pack_send.pkg_head));
    pkg_len += sizeof(msg_pack_send.pkg_head);

    if (cmd == FC_BOOT_FW_BLOCK) {
        // 当前读取位置
        curDataIndex = up_data_len * idx;

        // 读位置移到curDataIndex时
        fseek(file, curDataIndex, SEEK_SET);

        // 获取数据
        int ret = fread(msg_pack_send.content, 1, up_data_len, file);

        memcpy((char *)com_buf + pkg_len, (char *)&msg_pack_send.content, up_data_len);
        pkg_len += up_data_len;

        if (ret == -1) {    // 如果返回值为-1，则表示出现错误
            fclose(file);
            return -1;
        }

    } else if (cmd == FC_BOOT_START) {
        BUGLOG("update_file_idx %d  dst_module 0X%X", update_file_idx, msg_pack_send.pkg_head.dst_module);

        memcpy((char *)com_buf + pkg_len, &update_file_idx, up_data_len);
        pkg_len += up_data_len;
    } else {
        BUGLOG("update_file_idx %d  dst_module 0X%X", update_file_idx, msg_pack_send.pkg_head.dst_module);

        memcpy((char *)com_buf + pkg_len, &update_file_idx, up_data_len);
        pkg_len += up_data_len;
    }

    // 3.计算校验和CRC,先送低8位，后送高8位
    uint16_t crc = modbus_crc(com_buf + HEAD_LEN + CRC_LEN, pkg_len - CRC_LEN - HEAD_LEN);
    com_buf[2]   = (uint8_t)(crc);
    com_buf[3]   = (uint8_t)(crc >> 8);

    // BUGLOG("实际包的长度 %d = 头帧 %d + 数据长度 %d  ", pkg_len, sizeof(msg_pack_send.pkg_head),
    //        msg_pack_send.pkg_head.content_len);

    // BUGLOG("发送数据  ");
    // for (int i = 0; i < pkg_len; i++) {
    //     BUGLOG(" %02X", com_buf[i]);
    //     if (i % 16 == 15) {
    //         BUGLOG(" ");
    //     }
    // }
    // BUGLOG(" ");

    // 发送
    CommDataWrite((char *)com_buf, pkg_len);

    // BUGLOG("发送完成 ");
    return 0;
}

/**读取函数 */
int unpacke_recv(uint16_t *rx_data_len, task_ota_fb_t *recv) {
    uint8_t rx_msg_buf[UPDATE_PKGS_SIZE] = {0};
    uint32_t revice_index = 0;
    uint32_t rx_start_tick = getHighPrecisionTimeMillis();
    
    // BUGLOG("开始接收数据帧");
    
    // 第一阶段：寻找帧头
    while (revice_index < 2) {
        if (getHighPrecisionTimeMillis() - rx_start_tick > 1000) {
            BUGLOG("寻找帧头超时");
            return false;
        }
        
        uint32_t available_size = getRingbufferValidLen();
        if (available_size == 0) {
            Sleep(1);
            continue;
        }
        
        // 读取一个字节
        uint8_t byte;
        int read_bytes = CommDataRead(&byte, 1);
        if (read_bytes != 1) {
            BUGLOG("读取字节失败");
            continue;
        }
        
        // 检查帧头
        if (revice_index == 0 && byte == FRAME_HEAD_0) {
            rx_msg_buf[revice_index++] = byte;
            // BUGLOG("找到第一个帧头字节: 0x%02X", byte);
        } else if (revice_index == 1 && byte == FRAME_HEAD_1) {
            rx_msg_buf[revice_index++] = byte;
            // BUGLOG("找到第二个帧头字节: 0x%02X", byte);
        } else if (revice_index == 1 && byte != FRAME_HEAD_1) {
            // 第二个字节不是帧头，重新开始
            // BUGLOG("第二个字节不是帧头: 0x%02X，重新寻找", byte);
            revice_index = 0;
        } else if (revice_index == 0 && byte != FRAME_HEAD_0) {
            // 第一个字节不是帧头，继续寻找
            // BUGLOG("跳过非帧头字节: 0x%02X", byte);
        }
    }
    
    // 第二阶段：读取帧头剩余部分
    while (revice_index < sizeof(pack_head_t)) {
        if (getHighPrecisionTimeMillis() - rx_start_tick > 1000) {
            BUGLOG("读取帧头超时");
            return false;
        }
        
        uint32_t available_size = getRingbufferValidLen();
        if (available_size == 0) {
            Sleep(1);
            continue;
        }
        
        uint32_t remaining = sizeof(pack_head_t) - revice_index;
        int read_bytes = CommDataRead(rx_msg_buf + revice_index, remaining);
        if (read_bytes <= 0) {
            BUGLOG("读取帧头剩余部分失败");
            continue;
        }
        
        revice_index += read_bytes;
        // BUGLOG("读取帧头 %d 字节，总共 %u 字节", read_bytes, revice_index);
    }
    
    // 解析帧头
    pack_head_t *header = (pack_head_t *)rx_msg_buf;
    uint16_t content_len = header->content_len;
    // BUGLOG("帧头解析完成，内容长度: %u", content_len);
    
    // 处理内容长度为0的情况
    if (content_len == 0) {
        // BUGLOG("内容长度为0，处理为心跳包或确认包");
        *rx_data_len = 0;
        return true;
    }
    
    // 检查总长度是否超过缓冲区大小
    uint32_t total_len = sizeof(pack_head_t) + content_len;
    if (total_len > UPDATE_PKGS_SIZE) {
        BUGLOG("帧长度 %u 超过缓冲区大小 %u", total_len, UPDATE_PKGS_SIZE);
        return false;
    }
    
    // 第三阶段：读取内容部分
    while (revice_index < total_len) {
        if (getHighPrecisionTimeMillis() - rx_start_tick > 1000) {
            BUGLOG("读取内容超时");
            return false;
        }
        
        uint32_t available_size = getRingbufferValidLen();
        if (available_size == 0) {
            Sleep(1);
            continue;
        }
        
        uint32_t remaining = total_len - revice_index;
        int read_bytes = CommDataRead(rx_msg_buf + revice_index, remaining);
        if (read_bytes <= 0) {
            BUGLOG("读取内容失败");
            continue;
        }
        
        revice_index += read_bytes;
        // BUGLOG("读取内容 %d 字节，总共 %u 字节", read_bytes, revice_index);
    }
    
    // 计算CRC校验
    // 注意：需要确认CRC计算范围是否正确
    uint16_t crc = modbus_crc(rx_msg_buf + HEAD_LEN + CRC_LEN,
                            total_len - HEAD_LEN - CRC_LEN);
    
    // 获取接收到的CRC值
    uint16_t data_crc = header->check_L | (header->check_H << 8);
    
    // 调试输出：打印CRC计算细节
    // BUGLOG("CRC计算范围: 从偏移 %d 开始，长度 %u", HEAD_LEN + CRC_LEN, total_len - HEAD_LEN - CRC_LEN);
    // BUGLOG("CRC计算数据:");
    // for (uint32_t i = HEAD_LEN + CRC_LEN; i < total_len - CRC_LEN; i++) {
    //     if ((i - (HEAD_LEN + CRC_LEN)) % 16 == 0) BUGLOG("");
    //     BUGLOG("%02X ", rx_msg_buf[i]);
    // }
    // BUGLOG("");
    
    // CRC校验
    if (data_crc != crc) {
        BUGLOG("CRC校验失败，计算值: 0x%04X，接收值: 0x%04X", crc, data_crc);
        // 打印接收到的完整数据用于调试
        BUGLOG("接收到的完整数据:");
        for (uint32_t i = 0; i < revice_index; i++) {
            printf("%02X ", rx_msg_buf[i]);
        }
        BUGLOG("");
        return false;
    }
    
    // BUGLOG("CRC校验成功");
    
    // 拷贝有效数据到输出参数
    memcpy(recv, rx_msg_buf, sizeof(task_ota_fb_t));
    *rx_data_len = content_len;
    
    // BUGLOG("成功接收完整帧，内容长度: %u", *rx_data_len);
    // BUGLOG("回复数据: res = 0x%X, state = 0x%X, idx = %d", recv->result, recv->state, recv->index);
    
    return true;
}

// 读取json文件
void ReadJsonFile(const char *strFilePath) {
    // 读取 JSON 文件
    std::ifstream file(strFilePath);
    if (!file.is_open()) {
        std::cerr << "Error opening file!" << std::endl;
    }

    memset(&read_config_json, 0, sizeof(read_config_json));

    // 解析 JSON
    json data = json::parse(file);

    // 提取数据（带错误检查）
    if (data.contains("properties")) {
        const auto &props = data["properties"];

        // 提取src_module（字符串）
        if (props.contains("src_module") && props["src_module"].contains("data")) {
            std::string src_module_str = props["src_module"]["data"];
            // 转换为整数（可选）
            uint32_t src_module                  = std::stoul(src_module_str, nullptr, 16);
            read_config_json.pkg_head.src_module = src_module;    // 源模块ID
            BUGLOG("src_module: 0X%02X", src_module);
        }

        // 提取dst_module（字符串）
        if (props.contains("dst_module") && props["dst_module"].contains("data")) {
            std::string dst_module_str = props["dst_module"]["data"];
            // 转换为整数（可选）
            uint32_t dst_module                  = std::stoul(dst_module_str, nullptr, 16);
            read_config_json.pkg_head.dst_module = dst_module;    // 目的模块ID
            BUGLOG("dst_module: 0X%02X", dst_module);
        }

        // 提取fc（字符串）
        // if (props.contains("fc") && props["fc"].contains("data")) {
        //     std::string fc_str           = props["fc"]["data"];
        //     // 转换为整数（可选）
        //     uint32_t fc                  = std::stoul(fc_str, nullptr, 16);
        //     read_config_json.pkg_head.fc = fc;   // 功能码
        //     BUGLOG("fc: 0X%02X \n", fc);
        // }

        //  // 提取content数组
        // std::vector<int> content              = props["content"]["data"].get<std::vector<int>>();

        // // 获取数据长度
        // read_config_json.pkg_head.content_len = content.size();

        // for (size_t i = 0; i < content.size(); ++i) {
        //     read_config_json.content[i] = content[i];
        // }
        // BUGLOG("len : %d ,content :[ %d, %d, %d]", content.size(), read_config_json.content[0],
        //       read_config_json.content[1], read_config_json.content[2]);
    }
}

/**
 * @brief 升级MCU
 *
 * @content board_id
 * @content src_file
 * @return int
 */
int update_mcu(const char *src_file, const char *config_file) {
    int      ret                 = 0;
    char     full_file_name[256] = "";
    uint16_t read_data_len       = 0;
    int      send_idx            = 0;    // 发送的帧数

    BUGLOG("读取配置config.json文件  ");
    ReadJsonFile(config_file);

    BUGLOG("开始升级  ");
    sprintf(full_file_name, "%s", src_file);
    BUGLOG("解析文件 %s  ", full_file_name);

    file = fopen(full_file_name, "rb");    // 打开文件，注意检查是否成功打开
    if (file == NULL) {
        perror("Error opening file");
        return 1;    // 错误处理
    }

    fseek(file, 0, SEEK_END);         // 移动文件指针到末尾
    update_file_len = ftell(file);    // 获取文件大小
    fseek(file, 0, SEEK_SET);         // 移动文件指针到开头
    update_file_idx = update_file_len / UPDATE_PKGS_SIZE + 1;
    BUGLOG("update_mcu, length of %s :%d ,所需传递帧数 %d  ", full_file_name, update_file_len, update_file_idx);

    // 底层MCU可写flase大小
    // if (update_file_len > 219 * UPDATE_PKGS_SIZE) {
    //     BUGLOG("文件大小 (%d) 超过了 %d  ", update_file_len, 219 * UPDATE_PKGS_SIZE);
    //     ret = ERROR;
    //     return ret;
    // }

    BUGLOG("update_mcu -- 1 ");
    int    try_cnt     = 0;
    int    err_cnt     = 0;    // 丢帧数
    time_t currentTime = getHighPrecisionTimeMillis();
    time_t updata_time = getHighPrecisionTimeMillis();

    read_data_len = 0;
    memset(&msg_pack_rece, 0, sizeof(msg_pack_rece));
get_start_flag:
    send_idx     = 0;
    curDataIndex = 0;

    package_send(FC_BOOT_START, send_idx);
    currentTime = getHighPrecisionTimeMillis();

    read_data_len = 0;
    memset(&msg_pack_rece, 0, sizeof(msg_pack_rece));
    Sleep(10);
    while (1) {
        unpacke_recv(&read_data_len, &msg_pack_rece);
        // 未收到回复
        if (read_data_len <= 0) {
            if (try_cnt > 3) {
                BUGLOG("升级失败  未回复");
                ret = ERROR;
                return ret;
            }
            // 等待回复1S
            if (getHighPrecisionTimeMillis() - currentTime >= TIMEOUT_MAX) {
                try_cnt++;
                err_cnt++;
                BUGLOG("开始升级回复超时 %d 次数 ,content[ %d, %d, %d]", try_cnt, msg_pack_rece.result,
                       msg_pack_rece.state, msg_pack_rece.index);
                goto get_start_flag;
            }
            Sleep(10);
            continue;
        }

        if (msg_pack_rece.state == UPG_STA_BEGIN) {
            if (msg_pack_rece.result == ERR_SUCCESS) {
                BUGLOG("开始升级回复成功,准备下载... ");
                try_cnt = 0;
                break;
            } else if (msg_pack_rece.result == ERR_FLASH) {
                BUGLOG("擦错Flash失败,重新擦除");
                try_cnt++;
                err_cnt++;
                goto get_start_flag;
            } else {
                BUGLOG("未知参数 %02X ", msg_pack_rece.result);
                return msg_pack_rece.result;
            }
        } else if (msg_pack_rece.state == UPG_STA_UNDER) {
            BUGLOG("不是开始升级状态 [ %02x, %02X] ", msg_pack_rece.result, msg_pack_rece.state);
            try_cnt++;
            err_cnt++;
            goto get_start_flag;
        } else {
            BUGLOG("未知参数 [ %02x, %02X] ", msg_pack_rece.result, msg_pack_rece.state);
            try_cnt++;
            err_cnt++;
            goto get_start_flag;
        }
    }

    BUGLOG("update_mcu -- 2 ");

    int recv_idx = 1;    // 反馈的帧数
    try_cnt      = 0;
start_data:
    currentTime = getHighPrecisionTimeMillis();

    package_send(FC_BOOT_FW_BLOCK, send_idx);
    read_data_len = 0;
    // BUGLOG("发送帧数 idx %d  write len %d , curidx [ %d > %d]  %d ", send_idx, write_data,
    //        (curDataIndex + UPDATE_PKGS_SIZE), update_file_len, (curDataIndex + UPDATE_PKGS_SIZE) > update_file_len);
    memset(&msg_pack_rece, 0, sizeof(msg_pack_rece));
    Sleep(10);
    while (1) {
        unpacke_recv(&read_data_len, &msg_pack_rece);

        // 未收到回复
        if (read_data_len <= 0) {
            if (try_cnt > 3) {
                BUGLOG("升级失败,通讯中断");
                ret = ERROR;
                return ret;
            }
            // 等待回复5S
            if (getHighPrecisionTimeMillis() - currentTime > TIMEOUT_MAX) {
                try_cnt++;
                err_cnt++;
                BUGLOG("传输数据回复超时 %d 次数 ,idx: %d,content[ %x, %x]  ", try_cnt, send_idx, msg_pack_rece.result,
                       msg_pack_rece.state);
                goto start_data;
            }
            Sleep(10);
            continue;
        }

        // 反馈帧数
        recv_idx = msg_pack_rece.index;
        // 接收成功清空尝试次数
        try_cnt = 0;
        if (msg_pack_rece.state == UPG_STA_UNDER) {
            if (msg_pack_rece.result == ERR_SUCCESS) {
                // 下发数据帧数从0开始
                BUGLOG("正在下载...  反馈帧数：%d,  丢帧 %d, 下载进度: %.2f %% , time: %ld", recv_idx, err_cnt,
                       (float)(recv_idx + 1) * 100 / ((update_file_len / UPDATE_PKGS_SIZE) + 1),
                       getHighPrecisionTimeMillis() - updata_time);
                send_idx = recv_idx + 1;

                // 文件传输完成
                if ((curDataIndex + UPDATE_PKGS_SIZE) > update_file_len) {
                    break;
                }
                goto start_data;
            } else if (msg_pack_rece.result == ERR_OTA_ONE_TIMEOUT) {
                BUGLOG("单帧传输超时 ,升级失败 %d  ", recv_idx);
                return msg_pack_rece.result;
            } else if (msg_pack_rece.result == ERR_OTA_MAX_TIMEOUT) {
                BUGLOG("升级总时间超时 ,升级失败 %d ，时间：%ld  ", recv_idx,
                       getHighPrecisionTimeMillis() - updata_time);
                return msg_pack_rece.result;
            } else if (msg_pack_rece.result == ERR_OTA_NOT_START) {
                BUGLOG("未执行开始升级 ,重新升级 %d  ", recv_idx);
                return msg_pack_rece.result;
            } else if (msg_pack_rece.result == ERR_FLASH) {
                BUGLOG("Flash异常 ,需要重新传帧 %d ,result = %02X", recv_idx, msg_pack_rece.result);
                send_idx = recv_idx;
                try_cnt++;
                err_cnt++;
                goto start_data;
            } else if (msg_pack_rece.result == ERR_CMD_PARAM) {
                BUGLOG("上一帧和当前帧不连续 %d  ", recv_idx);
                return msg_pack_rece.result;
            } else {
                BUGLOG("未知参数 %x ", msg_pack_rece.result);
                return msg_pack_rece.result;
            }
        } else {
            BUGLOG("未知参数 [ %02x, %02X]  ", msg_pack_rece.result, msg_pack_rece.state);
            return msg_pack_rece.state;
        }
    }

    BUGLOG("update_mcu -- 3 ");

end_flag:
    package_send(FC_BOOT_END, 0);
    currentTime   = getHighPrecisionTimeMillis();
    read_data_len = 0;
    memset(&msg_pack_rece, 0, sizeof(msg_pack_rece));
    while (1) {
        unpacke_recv(&read_data_len, &msg_pack_rece);

        // 未收到回复
        if (read_data_len <= 0) {
            if (try_cnt > 3) {
                BUGLOG("通讯中断，升级失败");
                ret = ERROR;
                return ret;
            }
            // 等待回复5S
            if (getHighPrecisionTimeMillis() - currentTime > TIMEOUT_MAX) {
                try_cnt++;
                err_cnt++;
                BUGLOG("传输数据回复超时 %d 次数 ,idx: %d,content[ %x, %x]  ", try_cnt, send_idx, msg_pack_rece.result,
                       msg_pack_rece.state);
                goto end_flag;
            }
            Sleep(100);

            continue;
        }

        if (msg_pack_rece.state == UPG_STA_SUSS) {
            if (msg_pack_rece.result == ERR_SUCCESS) {
                BUGLOG("升级回复成功,准备复位");
                try_cnt = 0;
                break;
            } else if (msg_pack_rece.result == ERR_OTA_CHECKOUT) {
                BUGLOG("帧校验失败");
                return msg_pack_rece.result;
            } else {
                BUGLOG("未知参数 %02X  ", msg_pack_rece.result);
                return msg_pack_rece.result;
            }
        } else {
            BUGLOG("未知参数 [ %02x, %02X]  ", msg_pack_rece.result, msg_pack_rece.state);
            return msg_pack_rece.state;
        }
    }
    BUGLOG("update_mcu -- 4 ");
reset_flag:
    package_send(FC_REBOOT, 0);
    currentTime   = getHighPrecisionTimeMillis();
    read_data_len = 0;
    memset(&msg_pack_rece, 0, sizeof(msg_pack_rece));
    while (1) {
        unpacke_recv(&read_data_len, &msg_pack_rece);

        // 未收到回复
        if (read_data_len <= 0) {
            if (try_cnt > 3) {
                BUGLOG("通讯中断，复位失败");
                ret = ERROR;
                return ret;
            }
            // 等待回复5S
            if (getHighPrecisionTimeMillis() - currentTime > TIMEOUT_MAX) {
                try_cnt++;
                err_cnt++;
                BUGLOG("MCU复位回复超时 %d 次数 ,idx: %d,content[ %x, %x]  ", try_cnt, send_idx, msg_pack_rece.result,
                       msg_pack_rece.state);
                goto reset_flag;
            }
            Sleep(100);
            continue;
        }

        if (msg_pack_rece.result == ERR_SUCCESS && msg_pack_rece.state == UPG_STA_SUSS) {
            BUGLOG("MCU复位回复成功, content[ %x, %x] ", msg_pack_rece.result, msg_pack_rece.state);
            try_cnt = 0;
            break;
        } else {
            BUGLOG("未知参数 [ %02x, %02X]  ", msg_pack_rece.result, msg_pack_rece.state);
            return msg_pack_rece.state;
        }
    }
    BUGLOG("升级总时间 %ld  ", getHighPrecisionTimeMillis() - updata_time);
    BUGLOG("update_mcu -- finish ");
    fclose(file);    // 关闭文件
    return ret;
}

/**
 * @brief Get the Sys State object
 *
 * @return int
 */
int GetSysState(void) {
    time_t   currentTime   = getHighPrecisionTimeMillis();
    uint16_t read_data_len = 0;
    uint16_t try_cnt       = 0;
state_flag:
    // package_send(UPG_SET_STATE, 0);
    currentTime   = getHighPrecisionTimeMillis();
    read_data_len = 0;
    memset(&msg_pack_rece, 0, sizeof(msg_pack_rece));
    while (1) {
        unpacke_recv(&read_data_len, &msg_pack_rece);

        // 未收到回复
        if (read_data_len <= 0) {
            if (try_cnt > 3) {
                return false;
            }
            // 等待回复5S
            if (getHighPrecisionTimeMillis() - currentTime > TIMEOUT_MAX) {
                try_cnt++;
                BUGLOG("升级状态回复超时 %d 次数 ,content[ %x, %x] ", try_cnt, msg_pack_rece.result,
                       msg_pack_rece.state);
                goto state_flag;
            }
            Sleep(100);
            continue;
        }

        if (msg_pack_rece.state == UPG_STA_IDLE) {
            if (msg_pack_rece.result == ERR_SUCCESS) {
                BUGLOG("升级状态回复成功, content[ %x, %x] ", msg_pack_rece.result, msg_pack_rece.state);
                try_cnt = 0;
                break;
            } else {
                BUGLOG("未知参数 [ %02x, %02X]  ", msg_pack_rece.result, msg_pack_rece.state);
                return msg_pack_rece.result;
            }

        } else {
            BUGLOG("未知参数 [ %02x, %02X]  ", msg_pack_rece.result, msg_pack_rece.state);
            return msg_pack_rece.state;
        }
    }
    return true;
}